package com.bihua.iot.service.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.Method;
import com.bihua.common.helper.LoginHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bihua.common.core.domain.PageQuery;
import com.bihua.common.core.page.TableDataInfo;
import com.bihua.common.utils.StringUtils;
import com.bihua.iot.domain.RuleArrangement;
import com.bihua.iot.domain.bo.RuleArrangementBo;
import com.bihua.iot.domain.vo.RuleArrangementVo;
import com.bihua.iot.mapper.RuleArrangementMapper;
import com.bihua.iot.service.IRuleArrangementService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;

/**
 * 规则编排Service业务层处理
 *
 * @author bihua
 * @date 2023-07-03
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class RuleArrangementServiceImpl implements IRuleArrangementService {

    private final RuleArrangementMapper baseMapper;

    /**
     * 查询规则编排
     */
    @Override
    public RuleArrangementVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询规则编排列表
     */
    @Override
    public TableDataInfo<RuleArrangementVo> queryPageList(RuleArrangementBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<RuleArrangement> lqw = buildQueryWrapper(bo);
        Page<RuleArrangementVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询规则编排列表
     */
    @Override
    public List<RuleArrangementVo> queryList(RuleArrangementBo bo) {
        LambdaQueryWrapper<RuleArrangement> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<RuleArrangement> buildQueryWrapper(RuleArrangementBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<RuleArrangement> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getAppId()), RuleArrangement::getAppId, bo.getAppId());
        lqw.eq(StringUtils.isNotBlank(bo.getRuleNode()), RuleArrangement::getRuleNode, bo.getRuleNode());
        lqw.like(StringUtils.isNotBlank(bo.getRuleName()), RuleArrangement::getRuleName, bo.getRuleName());
        lqw.eq(StringUtils.isNotBlank(bo.getRuleIdentification()), RuleArrangement::getRuleIdentification, bo.getRuleIdentification());
        lqw.eq(StringUtils.isNotBlank(bo.getRuleContent()), RuleArrangement::getRuleContent, bo.getRuleContent());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), RuleArrangement::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增规则编排
     */
    @Override
    public Boolean insertByBo(RuleArrangementBo bo) {
        RuleArrangement add = BeanUtil.toBean(bo, RuleArrangement.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            String token = StpUtil.getTokenValue();
            String result = HttpUtil.createPost(StringUtils.format("{}{}",bo.getRuleNode(),"flow"))
                .auth(StringUtils.format("Bearer {}" ,token))
                .body(StringUtils.format("{\"id\":\"{}\",\"type\":\"tab\",\"label\":\"{}\",\"nodes\": [ ],\"configs\": [ ]}",add.getId(), add.getRuleName()), ContentType.JSON.getValue())
                .execute()
                .body();
            Map<String, Object> resultMap = JSONUtil.toBean(result, Map.class);
            if(ObjectUtil.isNotEmpty(resultMap.get("id"))){
                int updateFlag = baseMapper.updateRuleIdentificationById((String) resultMap.get("id"), add.getId());
                System.out.println("updateFlag:"+updateFlag);
            }
        }
        return flag;
    }

    /**
     * 修改规则编排
     */
    @Override
    public Boolean updateByBo(RuleArrangementBo bo) {
        RuleArrangement update = BeanUtil.toBean(bo, RuleArrangement.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    public Boolean updateRuleContent(String ruleIdentification) {
        String token = StpUtil.getTokenValue();
        RuleArrangement ruleArrangement= baseMapper.findOneByRuleIdentification(ruleIdentification);
        String ruleContent = HttpUtil.createGet(StringUtils.format("{}{}{}",ruleArrangement.getRuleNode(), "flow/", ruleIdentification))
            .auth(StringUtils.format("Bearer {}" ,token))
            .execute().body();
        int num = baseMapper.updateRuleContentByRuleIdentification(ruleContent, ruleIdentification);
        return num > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(RuleArrangement entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除规则编排
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        //删除规则引擎中规则
        List<RuleArrangementVo> ruleArrangements = baseMapper.selectVoBatchIds(ids);
        String token = StpUtil.getTokenValue();
        for (RuleArrangementVo vo : ruleArrangements) {
            final String result = HttpRequest.of(StringUtils.format("{}{}{}",vo.getRuleNode(), "flow/", vo.getRuleIdentification()))
                .method(Method.DELETE)
                .auth(StringUtils.format("Bearer {}" ,token))
                .execute()
                .body();
            log.info("delete rule identification[{}] result:{}", vo.getRuleIdentification(), result);
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
